import Collection from "../core/Collection";
import Obj from "../core/Obj";
import Comparator from "../utils/Comparator";

/**
 * 有序集合。 用户可以准确地控制每个元素在列表中的插入位置。 用户可以通过整数索引（在列表中的位置）访问元素，并在列表中搜索元素。
 *
 * 与集合不同，列表通常允许重复元素。
 *
 * List接口提供了对列表元素进行位置（索引）访问的方法{@link List#get}。List接口提供了两种方法来有效地在列表中的任意点插入和删除多个元素。
 *
 * @param E 需要存入此列表的元素类型
 * @version 1.0
 */
export default interface List<E> extends Obj, Collection<E> {

  /**
   * 对列表中的元素进行升序排序。
   *
   * 若提供了比较器，将使用此比较器进行大小比较，否则使用默认的比较方式。
   *
   * @param comparator 用于比较的比较器
   * @throws {UnsupportedOperationException} set方法不被此列表支持
   * @throws {IllegalArgumentException} 如果不给出比较器，存储的元素本身也不支持比较
   * @see Comparator
   * @see ComparableObj
   * @version 1.0
   */
  sort(comparator?: Comparator): void;

  /**
   * 返回在此列表对应索引位置的元素。
   *
   * @param index 需要取元素的索引
   * @return {E} 此列表中对饮元素位置的元素
   * @throws {IndexOutOfBoundException} 元素索引位置超出列表的范围
   * @version 1.0
   */
  get(index: number): E;

  /**
   * 用指定的元素替换此列表中指定位置的元素。
   *
   * @param index 要替换的元素的索引
   * @param e 需要替换的元素
   * @return {E} 原本位于此索引的元素
   * @throws {IndexOutOfBoundException} 元素索引位置超出列表的范围
   * @throws {UnsupportedOperationException} set方法不被此列表支持
   * @version 1.0
   */
  set(index: number, e: E): E;

  /**
   * 在此列表中的指定位置插入指定元素。 将当前在该位置的元素（如果有）和任何后续元素向右移动（向它们的索引添加一个）。
   *
   * @param index 需要被插入的索引
   * @param e 需要被插入的元素
   * @throws {IndexOutOfBoundException} 元素索引位置超出列表的范围
   * @throws {UnsupportedOperationException} addByIndex方法不被此列表支持
   * @version 1.0
   */
  addByIndex(index: number, e: E): void;

  /**
   * 移除此列表中指定位置的元素。 将任何后续元素向左移动（从它们的索引中减去一个）。
   *
   * 返回从列表中删除的元素。
   *
   * @param index 需要被删除的索引
   * @return {E} 被删除的元素
   * @throws {IndexOutOfBoundException} 元素索引位置超出列表的范围
   * @throws {UnsupportedOperationException} removeByIndex方法不被此列表支持
   * @version 1.0
   */
  removeByIndex(index: number): E;

  /**
   * 返回此列表中指定元素第一次出现的索引，如果此列表不包含该元素，则返回 -1。
   *
   * @param e 与需要寻找的元素相等的元素
   * @return {number} 此列表中指定元素第一次出现的索引，如果此列表没有，则为 -1
   * @version 1.0
   */
  indexOf(e: E): number;

  /**
   * 返回此列表中指定元素最后一次出现的索引，如果此列表不包含该元素，则返回 -1。
   *
   * @param e 与需要寻找的元素相等的元素
   * @return {number} 此列表中指定元素最后一次出现的索引，如果此列表没有，则为 -1
   * @version 1.0
   */
  lastIndexOf(e: E): number;

  /**
   * 返回此列表中指定的 fromIndex（含）和 toIndex（不含）之间的部分的视图。
   *
   * 如果 fromIndex 和 toIndex 相等，则返回的列表为空。
   *
   * 返回的列表是一个克隆列表，因此返回列表中的更改不会反映在此列表中，反之亦然。 返回的列表支持该列表支持的所有列表操作。
   *
   * @param fromIndex 子列表的起始索引（含）
   * @param endIndex 子列表的结束索引（不含）
   * @return {List<E>}此列表中指定范围的克隆列表
   * @throws {IllegalArgumentException} 索引超出范围或者起始索引大于结束索引
   * @version 1.0
   */
  subList(fromIndex: number, endIndex: number): List<E>;
}
